package threeD.Csg;

import twoD.Csg.CsgNode;
import inf.v3d.obj.*;

public class OctTreeNode {
	private OctTreeNode[] nodes;
	private double size;
	private double x;
	private double y;
	private double z;
	private boolean isHomogeneous_;

	public OctTreeNode(CsgNode N, double x, double y, double z, double size) {
		this.x = x;
		this.y = y;
		this.z = z;
		this.size = size;
		nodes = null;
	}

	private boolean isLeaf() {
		return nodes == null;
	}

	public boolean isHomogeneous() {
		return isHomogeneous_;
	}

	public void draw(CsgNode N, Polyline P) {
		if (this.isLeaf()) {
			if (!isHomogeneous_) {
				P.startNew();
				P.addVertex(x, y, z);
				P.addVertex(x + size, y, z);
				P.addVertex(x + size, y + size, z);
				P.addVertex(x, y + size, z);
				P.addVertex(x, y, z);
				P.addVertex(x, y, z + size);
				P.addVertex(x + size, y, z + size);
				P.addVertex(x + size, y + size, z + size);
				P.addVertex(x, y + size, z + size);
				P.addVertex(x, y, z + size);
				P.startNew();
				P.addVertex(x + size, y, z);
				P.addVertex(x + size, y, z + size);
				P.startNew();
				P.addVertex(x + size, y + size, z);
				P.addVertex(x + size, y + size, z + size);
				P.startNew();
				P.addVertex(x, y + size, z);
				P.addVertex(x, y + size, z + size);
			}
		} else {
			for (int i = 0; i < nodes.length; i++)
				nodes[i].draw(N, P);
		}
	}

	public void refine(CsgNode N, int depth) {
		if (!N.isUniform(this.x, this.y, this.z, this.size)) {
			nodes = new OctTreeNode[8];
			for (int i = 0; i < 2; i++) {
				for (int j = 0; j < 2; j++) {
					for (int k = 0; k < 2; k++) {
						nodes[i * 4 + j * 2 + k] = new OctTreeNode(N, this.x
								+ i * this.size / 2,
								this.y + j * this.size / 2, this.z + k
										* this.size / 2, this.size / 2);
						if (depth > 0)
							nodes[i * 4 + j * 2 + k].refine(N, depth - 1);
						else {
							if (!N.isUniform(this.x + i * this.size / 2, this.y
									+ j * this.size / 2, this.z + k * this.size
									/ 2, this.size / 2))
								nodes[i * 4 + j * 2 + k].isHomogeneous_ = false;
							else
								nodes[i * 4 + j * 2 + k].isHomogeneous_ = true;
						}
					}
				}
			}
			isHomogeneous_ = false;
		} else
			isHomogeneous_ = true;
	}
}
